<?php
namespace app\api\controller;

use app\extra\DBCont;
use app\extra\Response;
use EasyWeChat\Factory;
use think\Controller;
use think\Url;
/**
 * @title 支付接口
 * @description 接口说明：必须微信访问
 * @group 微信报名分销
 */
class Pay extends Controller
{
    use Response;
    private $weChat;
    public function __construct()
    {
        parent::__construct();
        if (env('APP_ENV') == 'product'){
            $dir = __DIR__.'/../../common/pay/product/';
        } else {
            $dir = __DIR__.'/../../common/pay/test/';
        }
        $config = [
            // 前面的appid什么的也得保留哦
            'app_id'             => env('WX_APP_ID'),
            'mch_id'             => env('WX_MCH_ID'),
            'key'                => env('WX_MCH_KEY'),
            'cert_path'          => $dir.'apiclient_cert.pem',
            'key_path'           => $dir.'apiclient_key.pem',
            'notify_url'         => fullPath('notify'),     // 你也可以在下单时单独设置来想覆盖它
        ];
        $this->weChat = Factory::payment($config);
    }
    /**
     * @title 微信支付
     * @description 接口说明
     * @author hardy
     * @url /api/pay/pay
     * @method GET
     *
     * @param name:id type:int require:1 default:1 other: desc:参赛的Member（成员）id，在：/api/Team和/api/Member的post接口都会返回id值，该id就是这个接口的参数
     *
     * @return 支付订单
     */
    public function pay($id){
        if(empty($id)){
            $this->responseFail('id必填');
        }
        $data = model('Member')->where('id', $id)->find();
        if (empty($data) || empty($data['bill'])){
            $this->responseFail('订单不存在');
        }
        $team_id = model('Member')->where('id', $id)->value('team_id');
        $match_id = model('Team')->where('id', $team_id)->value('match_id');
        $name = model('Match')->where('id', $match_id)->value('name', '');
        if (is_array($data['team_id'])){
            $team_id = $data['team_id']['key'];
        } else {
            $team_id = $data['team_id'];
        }
        if ($data['pay_state'] != DBCont::WAIT){
            $this->responseFail('订单状态异常');
        }
        $amount = (int)($data['amount']*100);
        if ($amount <= 0){
            $this->responseFail('金额异常');
        }
        $openid =model('WeChat')->where('id', $data['wechat_id'])->value('openid');
        if (empty($openid)){
            $this->responseFail('订单异常');
        }
        $result = $this->weChat->order->unify([
            'body' => "参加比赛费用：{$name}",
            'out_trade_no' => $data['bill'],
            'total_fee' => $amount,
            'notify_url' => Url('Pay/notify', '', true, true), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $openid,
        ]);
        $jssdk = $this->weChat->jssdk;
        $payData = $jssdk->bridgeConfig($result['prepay_id']);
        exit($payData);
    }
    /**
     * @title 微信支付失败回调
     * @description 微信支付失败回调
     * @author hardy
     * @url /api/pay/fail
     * @method GET
     *
     * @param name:id type:int require:1 default:1 other: desc:参赛的Member（成员）id，在：/api/Team和/api/Member的post接口都会返回id值，该id就是这个接口的参数
     *
     * @return 支付订单
     */
    public function fail($id){
        $member = model('Member')->where('id', $id)->find();
        if (empty($member) || $member->isEmpty()){
            $this->responseSuccess('订单不存在');
        }
        $team_id = model('Member')->where('id', $id)->value('team_id');
        $team = model('Team')->where('id', $team_id)->find();
        $status = model('Team')->where('id', $team_id)->value('status');
        $type = model('Team')->where('id', $team_id)->value('type');
        if (!empty($team) && !$team->isEmpty()){
            if ($status != 1 || $type == DBCont::PERSON){
                model('Team')->where('id', $team_id)->update(['status' => DBCont::CANCEL]);
            }
        }
        model('Member')->where('id', $id)->update([
            'pay_state' =>  DBCont::CANCEL
        ]);

    }
    public function index(){
        //sysLogs('微信支付回调', Url('Pay/notify', '', true, true));
        $data = getPersonInfo();
        if (empty($data) || empty($data['openid'])){
            $url = fullPath('index');
            $url = urlencode($url);
            header('location:'.fullPath('/api/WeChat/auth').'?redirect='.$url);
            exit;
        }
        $result = $this->weChat->order->unify([
            'body' => '测试支付接口',
            'out_trade_no' => uniqid(),
            'total_fee' => 1,//$amount,
            'notify_url' => fullPath('notify'), // 支付结果通知网址，如果不设置则会使用配置里的默认地址
            'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
            'openid' => $data['openid'],
        ]);
        $jssdk = $this->weChat->jssdk;
        $payData = $jssdk->bridgeConfig($result['prepay_id']);
        $this->view->assign('result', $payData);
        $this->view->assign('success_return_url', fullPath('/index/index/index'));
        return $this->view->fetch('index');
    }

    public function notify(){
        $response = $this->weChat->handlePaidNotify(function($message, $fail){
            sysLogs('微信支付回调', json_encode($message));
            if ($message['return_code'] === 'SUCCESS') {
                // 用户是否支付成功
                if ($message['result_code'] === 'SUCCESS') {
                    $res = $this->payHandle($message);
                    if($res === true){
                        return true;
                    } elseif(is_string($res)){
                        return $fail($res);
                    }
                }
            } else {
                return $fail('通信失败，请稍后再通知我');
            }
            return true;
        });
        $response->send();
    }
    private function payHandle($notify_param){
        try{
            $order = model('Member')->where('bill','=', $notify_param['out_trade_no'])->find();
            if (empty($order)){
                return true;
            }
            if ($order['pay_state'] != DBCont::WAIT){
                return true;
            }
            $team_id = model('Member')->where('id','=', $order['id'])->value('team_id');
            $data = [
                'id' => $order['id'],
                'pay_time' => time(),
                'order_id' => $notify_param['transaction_id'],
                'pay_state' => DBCont::SUCCESS,
                'pay_info' => json_encode($notify_param),
                'way' => DBCont::WECHAT,
            ];
            $model = model('Member');
            $model->startTrans();
            $r = $model->update($data);
            if ($r === false){
                \exception($model->getError());
            }
            $r = model('Team')->where('id','=', $team_id)->update(['status' => DBCont::SUCCESS]);
            if ($r === false){
                \exception(model('Team')->getError());
            }
            $model->commit();
            return true;
        } catch (\Exception $e){
            $model->rollback();
            sysLogs('微信支付回调异常', $e->getMessage());
            return false;
        }
    }
}